package password.bee.liciense;

import fileDemo.imageDemo.Base64Util;
import org.apache.log4j.Logger;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.Principal;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

public class Verifier {
    private static final Logger Log = Logger.getLogger(Verifier.class);
    private static final String TAG = Verifier.class.getName();
    private static final String CA_DN = "CN=www.beeboxes.com,OU=platform,O=beeboxes,L=beijing,ST=beijing,C=CN";
    private static boolean dbg = true;

    /**
     * verify if the signature is correct
     *
     * @param text        the plain text.
     * @param signature   the signature of text. signature is base64 encoded.
     * @param certificate certificate for public key extraction. ceritficate is base64 encoded.
     */
    public static boolean verifySignature(String text, String signature, String certificate) {
        try {
            if (dbg) {
                Log.error(TAG+ "=============================================================");
                Log.error(TAG+ text);
                Log.error(TAG+ signature);
                Log.error(TAG+ certificate);
                Log.error(TAG+ "=============================================================");
            }

            byte[] textByte = text.getBytes();
//            byte[] signatureByte = Base64.decode(signature, Base64.DEFAULT);
//            byte[] certByte = Base64.decode(certificate, Base64.DEFAULT);

            byte[] signatureByte = Base64Util.decode(signature);
            byte[] certByte = Base64Util.decode(certificate);

            CertificateFactory f = CertificateFactory.getInstance("X.509");
            InputStream certIn = new ByteArrayInputStream(certByte);
            X509Certificate cert = (X509Certificate) f.generateCertificate(certIn);
            PublicKey pk = cert.getPublicKey();

            Signature sig = Signature.getInstance("SHA256withRSA");
            sig.initVerify(pk);
            sig.update(textByte);
            return sig.verify(signatureByte);
        } catch (Exception e) {
            if (dbg) {
                Log.error(TAG+ "" + e.getMessage());
                e.printStackTrace();
            }
            return false;
        }

    }

    /**
     * check if the certificate is issued by Beeboxes
     *
     * @param certificate the certificate to be verified. certificate should be in base64 coded x509 der format
     */
    public static boolean verifyCertificate(String certificate) {
        if (dbg) {
            Log.error(TAG+ certificate);
        }

        PublicKey pubkey = null;
        X509Certificate targetCert = null;
        String aliasCA = null;

        try {
            CertificateFactory f = CertificateFactory.getInstance("X.509");
//            byte[] targetCertByte = Base64.decode(certificate, Base64.DEFAULT);

            byte[] targetCertByte = Base64Util.decode(certificate);

            InputStream targetCertIn = new ByteArrayInputStream(targetCertByte);
            targetCert = (X509Certificate) f.generateCertificate(targetCertIn);

            boolean found = false;
            //android 获取根证书代码
//            KeyStore ks = KeyStore.getInstance("AndroidCAStore");
//            TODO 平台差异
            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
            ks.load(null, null); //Load default system keystore
            Enumeration<String> aliases = ks.aliases();
            while (aliases.hasMoreElements()) {
                aliasCA = (String) aliases.nextElement();
                Certificate tempCert = ks.getCertificate(aliasCA);
                if (tempCert instanceof X509Certificate) {
                    X509Certificate tempX509Cert = (X509Certificate) tempCert;
                    Principal principal = tempX509Cert.getIssuerDN();
                    String issuerDn = principal.getName();
                    if (issuerDn.contains(CA_DN)) {//TODO 蜂盒的根证书
                        found = true;
                        break;
                    }
                }
            }

            Log.error("found ca???  "+found);
            if (found) {
                X509Certificate cert = (X509Certificate) ks.getCertificate(aliasCA);
                pubkey = cert.getPublicKey();
            } else {
                return false;
            }

            if (pubkey != null && targetCert != null) {
                targetCert.verify(pubkey);
                return true;
            }
        } catch (Exception e) {
            if (dbg) {
                Log.error(TAG+ "" + e.getMessage());
                e.printStackTrace();
            }
            return false;
        }

        return false;
    }

}
